package com.useeinfo.framework.sugar.tools;

import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;

public class HttpClientUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    private PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();

    //创建http request的配置信息
    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(CONNECT_TIMEOUT)
            .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
            .setSocketTimeout(SOCKET_TIMEOUT)
            .build();

    //设置连接池线程最大数量
    private static final Integer MAX_CONNECTION = 500;

    //设置单个路由最大的连接线程数量
    private static final Integer MAX_ROUTE_TOTAL = 100;

    //连接上远程主机的时间(毫秒)
    private static final Integer CONNECT_TIMEOUT = 3000;
    //获取Connection对象的时间(毫秒)
    private static final Integer CONNECTION_REQUEST_TIMEOUT = 4000;
    //获取响应数据的时间(毫秒)
    private static final Integer SOCKET_TIMEOUT = 4000;

    private static final HttpClientUtil httpInstance = new HttpClientUtil();

    public static enum RequestMethod {
        HTTP_POST, HTTP_GET
    }

    private HttpClientUtil() {

        logger.debug("Start to init HttpClientUtilNoSSL object.");

        //创建httpclient连接池
        connectionManager.setMaxTotal(MAX_CONNECTION);
        connectionManager.setDefaultMaxPerRoute(MAX_ROUTE_TOTAL);

        logger.debug("Init HttpClientUtilNoSSL object success.");
    }

    //单例模式
    public static HttpClientUtil getInstance() {
        logger.debug("Someone got an instance of HttpClientUtilNoSSL with HTTP support.");
        return httpInstance;
    }


    public JSONObject httpGetRequest(String url, String body) {
        logger.debug("Start http request: {}, with request method: GET and body: {}", url, body);

        JSONObject result = null;

        //初始化httpclient客户端
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        //创建httpclient请求方式
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Connection", "close");
        logger.debug("It's a GET request.");

        CloseableHttpResponse response = null;

        try {
            //执行请求
            response = httpClient.execute(httpGet);

            //获得响应的消息实体
            HttpEntity entity = response.getEntity();

            //获取响应状态码
            int statusCode = response.getStatusLine().getStatusCode();

            //根据响应状态码进行处理
            switch (statusCode) {
                case 200://请求返回成功
                    logger.debug("HTTP RETURN CODE 200.");
                    InputStream inputStream = entity.getContent();
                    byte[] contentBytes = IOUtils.toByteArray(inputStream);
                    String responseStr = new String(contentBytes, "UTF-8");
                    logger.debug("Response content: {}", responseStr);

                    //关闭httpEntity流
                    EntityUtils.consumeQuietly(entity);
                    result = JSONObject.fromObject(responseStr);
                    break;

                default:
                    logger.error("RESPONSE CODE IS NOT 200.");
                    break;
            }
        } catch (IOException e) {
            logger.error("HTTP Request Exception!", e);
            httpGet.abort();
        } finally {
            if (null != response) {
                try {
                    //关闭response
                    response.close();
//                    httpClient.close();
                    logger.debug("Close response object success.");
                } catch (IOException e) {
                    logger.error("Close response object error.", e);
                }
            }
        }
        return result;
    }

    public JSONObject httpPostRequest(String url, String body) {
        logger.debug("Start http request: {}, with request method: GET and body: {}", url, body);

        JSONObject result = null;

        //初始化httpclient客户端
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        logger.debug("It's a POST request.");
        HttpPost httpPost = new HttpPost(url);
        //创建httpclient请求方式
        httpPost.setHeader("Connection", "close");
        logger.debug("It's a POST request.");

        if (StringUtils.isNotEmpty(body)) {
			logger.debug("It's a POST request with request body exist.");
			StringEntity entity = null;
			entity = new StringEntity(body, "UTF-8");
			httpPost.setEntity(entity);
        }

        CloseableHttpResponse response = null;

        try {
            //执行请求
            response = httpClient.execute(httpPost);

            //获得响应的消息实体
            HttpEntity entity = response.getEntity();

            //获取响应状态码
            int statusCode = response.getStatusLine().getStatusCode();

            //根据响应状态码进行处理
            switch (statusCode) {
                case 200://请求返回成功
                    logger.debug("HTTP RETURN CODE 200.");
                    InputStream inputStream = entity.getContent();
                    byte[] contentBytes = IOUtils.toByteArray(inputStream);
                    String responseStr = new String(contentBytes, "UTF-8");
                    logger.debug("Response content: {}", responseStr);

                    //关闭httpEntity流
                    EntityUtils.consumeQuietly(entity);
                    result = JSONObject.fromObject(responseStr);
                    break;

                default:
                    logger.error("RESPONSE CODE IS NOT 200.");
                    break;
            }
        } catch (IOException e) {
            logger.error("HTTP Request Exception!", e);
            httpPost.abort();
        } finally {
            if (null != response) {
                try {
                    //关闭response
                    response.close();
//                    httpClient.close();
                    logger.debug("Close response object success.");
                } catch (IOException e) {
                    logger.error("Close response object error.", e);
                }
            }
        }
        return result;
    }
//    public String sslRequest(String url, String body) {
//        logger.debug("Start http request: {}, with request method: GET and body: {}", url, body);
//
//        String result = null;
//
//        logger.debug("It's a SSL request, so do something special.");
//        //初始化SSL信息
//        SSLConnectionSocketFactory sslsf = null;
//        try {
//            KeyStore keyStore = KeyStore.getInstance("PKCS12");
//
//            //TODO:加载证书
//            FileInputStream instream = new FileInputStream(new File("D:\\JavaSoft\\Tomcat8\\webapps\\lotteryCar\\apiclient_cert.p12"));//加载本地的证书进行https加密传输
//
//            try {
//                keyStore.load(instream, HttpClientConfigure.getCertPassword().toCharArray());//设置证书密码
//            } catch (Exception e) {
//                e.printStackTrace();
//            } finally {
//                instream.close();
//            }
//
//            // Trust own CA and all self-signed certs
//            SSLContext sslcontext = SSLContexts.custom()
//                    .loadKeyMaterial(keyStore, HttpClientConfigure.getCertPassword().toCharArray())
//                    .build();
//            // Allow TLSv1 protocol only
//            sslsf = new SSLConnectionSocketFactory(
//                    sslcontext,
//                    new String[]{"TLSv1"},
//                    null,
//                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        CloseableHttpClient httpClient = HttpClients.custom()
//                .setConnectionManager(connectionManager)
//                .setDefaultRequestConfig(requestConfig)
//                .setSSLSocketFactory(sslsf)
//                .build();
//
//        logger.debug("It's a POST request.");
//        HttpPost httpPost = new HttpPost(url);
//        //创建httpclient请求方式
//        httpPost.setHeader("Connection", "close");
//        httpPost.addHeader("Content-Type", "text/xml");
//        httpPost.setEntity(new StringEntity(body, "UTF-8"));
//
//        logger.debug("It's a POST request.");
//
//        if (StringUtils.isNoneBlank(body)) {
//            logger.debug("It's a POST request with request body exist.");
//            StringEntity entity = null;
//            try {
//                entity = new StringEntity(body);
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//            httpPost.setEntity(entity);
//        }
//
//        CloseableHttpResponse response = null;
//
//        try {
//            //执行请求
//            response = httpClient.execute(httpPost);
//
//            //获得响应的消息实体
//            HttpEntity entity = response.getEntity();
//
//            //获取响应状态码
//            int statusCode = response.getStatusLine().getStatusCode();
//
//            //根据响应状态码进行处理
//            switch (statusCode) {
//                case 200://请求返回成功
//                    logger.debug("HTTP RETURN CODE 200.");
//                    result = EntityUtils.toString(entity, "UTF-8");
//                    logger.debug("Response content: {}", result);
//
//                    //关闭httpEntity流
//                    EntityUtils.consumeQuietly(entity);
//                    break;
//
//                default:
//                    logger.error("RESPONSE CODE IS NOT 200.");
//                    break;
//            }
//        } catch (IOException e) {
//            logger.error("HTTP Request Exception!", e);
//            httpPost.abort();
//        } finally {
//            if (null != response) {
//                try {
//                    //关闭response
//                    response.close();
////                    httpClient.close();
//                    logger.debug("Close response object success.");
//                } catch (IOException e) {
//                    logger.error("Close response object error.", e);
//                }
//            }
//        }
//
//        return result;
//    }

    public JSONObject httpRequest(String url, String requestMethod, String body) {
        if ("post".equalsIgnoreCase(requestMethod)) {
            return httpPostRequest(url, body);
        } else if ("get".equalsIgnoreCase(requestMethod)) {
            return httpGetRequest(url, body);
        } else {
            return null;
        }
    }
}
